const PORT = 6600;

var io = require('socket.io').listen(PORT);
var PlayerManager = require('./PlayerManager');
var viewId;
var gaming = false;

io.configure(function() {
  io.enable('browser client etag');
  io.enable('browser client gzip');
  io.set('log level', 3);
  io.set('close timeout', 5);
//  io.set('heartbeat timeout', 5);
//  io.set('polling duration', 5);
//  io.set('heartbeat interval', 10);
  console.log('z');

  io.set('transports', [
    //'websocket'
  'flashsocket'
  //, 'htmlfile'
 // , 'xhr-polling'
 // , 'jsonp-polling'
  ]);
});

io.sockets.on('connection', function (socket) {
  var sid = socket.id;

  socket.on('throw_request', function (player) {
    var id = PlayerManager.getIdByName(player);
    Util.emit(id, 'throw_request', null);
  });

  socket.on('throw_response', function(result, fn) {
    if (viewId) {
      fn();
      var name = PlayerManager.getNameById(sid);
      Util.emit(viewId, 'throw_response', {
        name: name,
        result: result
      });
    } else {
      socket.emit('view_not_ready', 'view');
    }
  });

  socket.on('view_ready', function(n, fn) {
    viewId = sid;
    fn();
  });

  socket.on('login', function(n, fn) {
    if (viewId) {
      fn();
      var userNumber = PlayerManager.getUserNumber();
      var result;
      var name;
      if (userNumber == 2) {
        result = 'player_number_limit';
      } else {
        result = 'login_success';
        if (userNumber == 0) {
          name = 'A';
        } else if (userNumber == 1) {
          name = 'B';
          Util.broadcast('game_start', {
            startBy: 'A'
          });
          gaming = true;
        }
        PlayerManager.addUser(sid, name);
        Util.emit(viewId, 'login', name);
      }

      socket.emit('login_result', {
        result: result,
        name: name
      });
    } else {
      socket.emit('view_not_ready', 'view');
    }
  });

  // Sent from view.
  socket.on('game_end', function(data) {
    socket.broadcast.emit('game_end', data);
    PlayerManager.clearUsers();
    viewId = null;
    gaming = false;
  });

  // Handle client disconnection
  socket.on('disconnect', function() {
    if (PlayerManager.hasUserWithId(sid)) {
      var name = PlayerManager.getNameById(sid);

      // Stop game if one player disconnected and game goes on.
      if (gaming) {
        Util.emit(viewId, 'stop_game', name);
        PlayerManager.clearUsers();
      } else {
        Util.emit(viewId, 'remove_player', name);
        PlayerManager.removeUser(sid);
      }
    } else if (sid == viewId) {
      // View page disconnected.
      PlayerManager.clearUsers();
      socket.broadcast.emit('disconnect_view', 'view');
    }
    console.log('disconnect');
  });

  socket.on('reconnect_failed', function() {
    console.log('reconnect_failed');
  });
  
  socket.on('close', function() {
    console.log('closed!');
  });
});

io.sockets.on('reconnect_failed', function() {
    console.log('io sockets reconnect_failed');
  });

io.sockets.on('close', function() {
    console.log('io sockets closed!');
  });

var Util = {
  /**
   * Emit registered websocket event of specified session.
   * @param {Number} sid Session id.
   * @param {String} event Event name.
   * @param {Object} data Data to be sent.
   */
  emit: function(sid, event, data) {
    io.sockets.socket(sid).emit(event, data);
  },

  broadcast: function(event, data) {
    io.sockets.emit(event, data);
  }
};